﻿using System;
using System.Collections.Generic;
using DDDNorthWind.Core.Bus;
using DDDNorthWind.Core.Domain.Events;
using DDDNorthWind.Core.Message;
using DDDNorthWind.Core.MessageHandler;

namespace DDDNorthWind.Bus
{
    public class DirectBus : IBus
    {

        public IFluentBus<TMessage> WithMessage<TMessage>(TMessage message) where TMessage : class, IMessage
        {
            var fluentBusFactory = new FluentBusFactory();

            return fluentBusFactory.Create<TMessage>(this).SetMensaje(message);
        }

        


        public IBus RegisterHandler<TMessage>(IMessageHandler<TMessage> messageHandler) where TMessage : IMessage
        {
            List<Action<IMessage>> handlers;
            if (!routes.TryGetValue(typeof(TMessage), out handlers))
            {
                handlers = new List<Action<IMessage>>();
                routes.Add(typeof(TMessage), handlers);
            }
            messageHandler.Bus = this;
            handlers.Add(DelegateAdjuster.CastArgument<IMessage, TMessage>(x => messageHandler.Handler(x)));

            return this;
        }


        private readonly Dictionary<Type, List<Action<IMessage>>> routes = new Dictionary<Type, List<Action<IMessage>>>();

        public virtual void Send<TMessage>(TMessage message) where TMessage : IMessage
        {
            List<Action<IMessage>> handlers;
            if (routes.TryGetValue(typeof(TMessage), out handlers))
            {
                foreach (var handler in handlers)
                {
                    //dispatch on thread pool for added awesomeness
                    handler.Invoke(message);
                }

            }
            else
            {
                throw new InvalidOperationException("no handler registered");
            }
        }


        IFluentBus<TMessage> IBusToFluentBus.WithMessage<TMessage>(TMessage message)
        {
            throw new NotImplementedException();
        }
    }
}
